<template>
  <view class="uni-list">
    <view class="uni-list-cell cell-pd">
      <view class="uni-uploader">
        <view class="uni-uploader-body">
          <view class="uni-uploader__files">
            <block v-for="(item, index) in fileList" :key="item.id">
              <view class="uni-uploader__file" :style="size === 'small' ? 'height:110rpx;width: 110rpx;' : ''">
                <image
                  class="uni-uploader__img"
                  :style="size === 'small' ? 'height:110rpx;width: 110rpx;' : ''"
                  :src="item.tempUrl"
                  :data-src="item.tempUrl"
                  @tap="previewImage(item.tempUrl)"
                  mode="aspectFill"
                ></image>
                <view v-if="item.status === 'processing'" class="uni-uploader__process">
                  <view>{{ item.processing }}%</view>
                  <view>正在上传中</view>
                </view>
                <view v-if="item.status === 'fail'" class="uni-uploader__process">
                  <view class="uni-uploader__error">上传失败</view>
                </view>
                <uni-icons
                  v-if="deletable && item.status !== 'processing'"
                  class="del-icon"
                  type="clear"
                  color="#c8c7cc"
                  size="30"
                  @click="delImage(index)"
                ></uni-icons>
              </view>
            </block>
            <view
              v-if="addable"
              class="uni-uploader__input-box"
              :style="size === 'small' ? 'height:110rpx;width: 110rpx;' : ''"
            >
              <view
                class="uni-uploader__input"
                @tap="chooseImage"
                :style="size === 'small' ? 'height:110rpx;width: 110rpx;' : ''"
              >
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>
<script>
import permision from '@/common/permission.js'
import { getToken } from '@/utils/auth'
import config from '@/config'
import { guid } from '@/pages/work/person-stat/util/index.js'
const sourceType = [['camera'], ['album'], ['camera', 'album']]
const sizeType = [['compressed'], ['original'], ['compressed', 'original']]
export default {
  name: 'ImageUpload',
  props: {
    // 数量限制
    limit: {
      type: Number,
      default: 3
    },
    // 组件状态
    state: {
      type: String,
      default: 'view'
    },
    // 多个地址逗号分隔
    imageUrl: {
      type: String,
      default: ''
    },
    // 0表示相机，1，表示相册，2表示默认（都有）
    sourceTypeIndex: {
      type: Number,
      default: 2
    },
    // 0表示压缩图， 1表示原图，2表示默认（都有）
    sizeTypeIndex: {
      type: Number,
      default: 2
    },
    size: {
      type: String,
      default: 'big'
    }
  },
  data() {
    return {
      staticDomain: config.staticUrl,
      fileList: []
    }
  },
  created() {
    if (this.imageUrl && this.imageUrl.length > 0) {
      this.fileList = this.imageUrl.split(',').map((item) => {
        return {
          status: 'success',
          processing: 100,
          tempUrl: config.staticUrl + item,
          url: item,
          id: guid()
        }
      })
    }
  },
  computed: {
    deletable() {
      return this.state === 'edit'
    },
    addable() {
      return this.state === 'edit' && this.fileList.length < this.limit
    }
  },
  watch: {
    imageUrl(newImageUrl) {
      if (newImageUrl) {
        const images = newImageUrl.split(',')
        const newImages = []
        images.forEach((item) => {
          if (this.fileList.findIndex((pet) => pet.url === item) === -1) {
            newImages.push({
              status: 'success',
              processing: 100,
              tempUrl: config.staticUrl + item,
              url: item,
              id: guid()
            })
          }
        })
        if (newImages.length) {
          this.fileList = this.fileList.concat(newImages)
        }
      } else {
        this.fileList = []
      }
    }
  },
  methods: {
    chooseImage: async function () {
      // #ifdef APP-PLUS
      // TODO 选择相机或相册时 需要弹出actionsheet，目前无法获得是相机还是相册，在失败回调中处理
      if (this.sourceTypeIndex !== 2) {
        let status = await this.checkPermission()
        if (status !== 1) {
          return
        }
      }
      // #endif
      if (this.isFullImage(this.fileList.length)) {
        return
      }
      uni.chooseImage({
        sourceType: sourceType[this.sourceTypeIndex],
        sizeType: sizeType[this.sizeTypeIndex],
        count: this.limit - this.fileList.length,
        success: (res) => {
          const total = res.tempFiles.length + this.fileList.length
          if (this.isFullImage(total)) {
            return
          }
          const tempFiles = res.tempFiles
          const _that = this
          for (let i = 0; i < tempFiles.length; i++) {
            const fileObj = {
              status: 'processing',
              processing: 0,
              tempUrl: tempFiles[i].path,
              url: '',
              id: guid()
            }
            this.fileList.push(fileObj)
            fileObj.uploadTask = uni.uploadFile({
              url: config.baseUrl + '/portal/file/upload-image-public',
              header: {
                Authorization: getToken(),
                'X-Aggregation-App-Id': config.aggregationAppid
              },
              filePath: tempFiles[i].path,
              name: 'file',
              success: (res) => {
                if (res.statusCode === 200) {
                  const result = JSON.parse(res.data)
                  if (result.code === 200) {
                    fileObj.url = result.data.relativeUrl
                    fileObj.status = 'success'
                    _that.emitChange()
                  } else {
                    fileObj.status = 'fail'
                  }
                } else {
                  fileObj.status = 'fail'
                }
              },
              fail: (res) => {
                fileObj.status = 'fail'
              }
            })
            fileObj.uploadTask.onProgressUpdate((res) => {
              fileObj.processing = parseInt(res.progress)
            })
          }
        },
        fail: (err) => {
          // #ifdef APP-PLUS
          if (err['code'] && err.code !== 0 && this.sourceTypeIndex === 2) {
            this.checkPermission(err.code)
          }
          // #endif
          // #ifdef MP
          if (err.errMsg.indexOf('cancel') !== '-1') {
            return
          }
          uni.getSetting({
            success: (res) => {
              let authStatus = false
              switch (this.sourceTypeIndex) {
                case 0:
                  authStatus = res.authSetting['scope.camera']
                  break
                case 1:
                  authStatus = res.authSetting['scope.album']
                  break
                case 2:
                  authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera']
                  break
                default:
                  break
              }
              if (!authStatus) {
                uni.showModal({
                  title: '授权失败',
                  content: '需要使用相机或相册，请在设置界面打开相关权限',
                  success: (res) => {
                    if (res.confirm) {
                      uni.openSetting()
                    }
                  }
                })
              }
            }
          })
          // #endif
        }
      })
    },
    delImage: function (index) {
      this.fileList.splice(index, 1)
      this.emitChange()
    },
    emitChange() {
      const images = this.fileList.filter((item) => item.url)
      this.$emit(
        'change',
        images.map((item) => item.url)
      )
    },
    isFullImage: function (num) {
      if (num > this.limit) {
        this.$modal.showToast('最多只能上传' + this.limit + '张图片')
        return true
      }
      return false
    },
    previewImage: function (image) {
      const current = this.staticDomain + image
      const urls = this.fileList.map((item) => {
        return item.tempUrl
      })
      uni.previewImage({
        current: current,
        urls: urls
      })
    },
    async checkPermission(code) {
      let type = code ? code - 1 : this.sourceTypeIndex
      let status = permision.isIOS
        ? await permision.requestIOS(sourceType[type][0])
        : await permision.requestAndroid(
            type === 0 ? 'android.permission.CAMERA' : 'android.permission.READ_EXTERNAL_STORAGE'
          )
      if (status === null || status === 1) {
        status = 1
      } else {
        uni.showModal({
          content: '没有开启权限',
          confirmText: '设置',
          success: function (res) {
            if (res.confirm) {
              permision.gotoAppSetting()
            }
          }
        })
      }
      return status
    }
  }
}
</script>

<style lang="scss" scoped>
.del-icon {
  position: absolute;
  z-index: 4;
  top: 0;
  right: 0;
}
.uni-list {
  width: auto;
}

.uni-list:after {
  height: 0;
}
.uni-uploader__process {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.4);
  view {
    color: #fff;
    font-size: 30rpx;
  }
  view.uni-uploader__error {
    color: #f44;
  }
}
</style>
